package auth

import (
	"context"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/user/model"
	"mall/service/user/rpc/internal/svc"
	"mall/service/user/rpc/types/user"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserInfoByAuthKeyLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetUserInfoByAuthKeyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserInfoByAuthKeyLogic {
	return &GetUserInfoByAuthKeyLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetUserInfoByAuthKeyLogic) GetUserInfoByAuthKey(in *user.GetUserInfoByAuthKeyReq) (*user.GetUserInfoResp, error) {
	if in.PlatformId == nil || *in.PlatformId == 0 {
		return nil, resultx.StatusError(resultx.USER_AUTH_PARAM_INVALID, "")
	}

	if in.AuthKey == nil || len(strings.TrimSpace(*in.AuthKey)) == 0 {
		return nil, resultx.StatusError(resultx.USER_AUTH_PARAM_INVALID, "")
	}

	platformId := *in.PlatformId
	authKey := strings.TrimSpace(*in.AuthKey)

	// 查询用户是否存在
	filterMap := make(map[string]map[string][]any)
	switch platformId {
	case globalkey.ThirdPartyPlatformWechatMini:
		filterMap[model.UserAuthColumns.PlatformID] = map[string][]any{
			"equalTo": []any{platformId},
		}
		filterMap[model.UserAuthColumns.Openid] = map[string][]any{
			"equalTo": []any{authKey},
		}
	}
	authList, _, err := l.svcCtx.CurrentUser.GetAuthList(l.ctx, model.M{
		"pageSize": uint64(1),
		"select":   model.UserAuthColumns.UserID,
		"orderBy":  model.UserAuthColumns.UserAuthID + " DESC",
	}, -1, filterMap)
	if err != nil {
		return nil, err
	}

	resp := &user.GetUserInfoResp{}
	if len(authList) == 0 {
		return resp, nil
	}

	userId := authList[0].UserID
	var userInfo *model.User

	if in.Force != nil && *in.Force > 0 {
		res, err := l.svcCtx.CurrentUser.FindOneNoCache(l.ctx, nil, userId)
		if err != nil {
			return nil, err
		}

		if res.UserStatus == uint16(globalkey.StatusAsGuest) {
			res.UserStatus = uint16(globalkey.StatusEnabled)
			err = l.svcCtx.CurrentUser.Update(l.ctx, nil, res, nil)
			if err != nil {
				return nil, err
			}
		}

		userInfo = res
	} else {
		res, err := l.svcCtx.CurrentUser.FindOne(l.ctx, userId)
		if err != nil {
			return nil, err
		}

		userInfo = res
	}

	detailFilterMap := make(map[string]map[string][]any)
	detailFilterMap[model.UserDetailColumns.UserID] = map[string][]any{
		"equalTo": []any{userId},
	}
	detailList, _, err := l.svcCtx.User.GetDetailList(l.ctx, model.M{
		"pageSize": uint64(1),
		"select":   model.UserDetailColumns.Role,
	}, -1, detailFilterMap)
	if err != nil {
		return nil, err
	}

	if len(detailList) == 0 {
		return resp, nil
	}

	role := detailList[0].Role

	accountFilterMap := make(map[string]map[string][]any)
	accountFilterMap[model.UserAccountColumns.UserID] = map[string][]any{
		"equalTo": []any{userId},
	}
	accountList, _, err := l.svcCtx.CurrentUser.GetAccountList(l.ctx, model.M{
		"pageSize": uint64(1),
		"select":   model.UserAccountColumns.RankID,
	}, -1, accountFilterMap)
	if err != nil {
		return nil, err
	}

	if len(accountList) == 0 {
		return resp, nil
	}

	rankId := accountList[0].RankID

	return &user.GetUserInfoResp{
		User: &user.TmpUserInfo{
			Id:     pointy.GetPointer(strconv.FormatInt(int64(userId), 10)),
			Status: pointy.GetPointer(uint32(userInfo.UserStatus)),
		},
		UserDetail: &user.UserDetailInfo{
			Role: pointy.GetPointer(uint32(role)),
		},
		UserAccount: &user.TmpUserAccountInfo{
			RankId: pointy.GetPointer(uint64(rankId)),
		},
	}, nil
}
